library(stringr)
library(tidyverse)
library(bigrquery)
response <- try(system('~/google-cloud-sdk/bin/gcloud projects list --quiet', intern = T))
projectid <- strsplit(response[2], " ")[[1]][1]
options(na.action = "na.fail")
source("./dredge_functions.R")
dredge_and_subset <- function(data) {
model <- lm(
presence_ratio ~ foraging_niche + trophic_niche + is_noctural + pc1 + pc2 + pc3 + pc4 + iucn_red_list_2020 + realm,
data=data
)
dredge_result <- dredge(model)
summary(model.avg(dredge_result, subset = delta < 10))
}
load_species_data <- function(poolname) {
filename <- str_replace('species_metrics_##POOL_NAME##.csv', '##POOL_NAME##', poolname)
if (!file.exists(filename)) {
column_name = str_replace_all('present_in_##POOL_NAME##_pool', '##POOL_NAME##', poolname)
if (poolname == 'both') {
column_name = 'present_in_both_pools'
}
sql <- str_replace_all("
WITH species AS (
SELECT
scientific_name,
count(*) AS regional_pool_count,
countif(present_in_city = true) AS city_count
FROM model.regional_species_filtered
JOIN model.taxonomy USING (scientific_name)
WHERE ##COL_SELECT## = true
GROUP BY scientific_name
)
SELECT
species.*,
body_morphspace.pc1,
body_morphspace.pc2,
body_morphspace.pc3,
body_morphspace.pc4,
trophic_niche,
foraging_niche,
is_noctural,
iucn_red_list_2020,
realm,
ttc.cluster,
ttc.cluster_half,
ttc.cluster_double
FROM species
JOIN model.taxonomy USING (scientific_name)
JOIN datasci.taxonomic_trait_clusters ttc USING (scientific_name)", '##COL_SELECT##', column_name)
tb <- bq_project_query(projectid, sql)
data <- bq_table_download(tb)
write_csv(data, filename)
}
data <- read_csv(filename)
data[is.na(data$foraging_niche),]$foraging_niche <- 'Omnivore'
data$foraging_niche = as.factor(data$foraging_niche)
data$trophic_niche = as.factor(data$trophic_niche)
data$is_noctural = as.factor(data$is_noctural)
data$presence_ratio = data$city_count / data$regional_pool_count
data$iucn_red_list_2020 = as.factor(data$iucn_red_list_2020)
data$realm = as.factor(data$realm)
data
}
merlin_data <- load_species_data('merlin')
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
scientific_name = col_character(),
regional_pool_count = col_double(),
city_count = col_double(),
pc1 = col_double(),
pc2 = col_double(),
pc3 = col_double(),
pc4 = col_double(),
trophic_niche = col_character(),
foraging_niche = col_character(),
is_noctural = col_logical(),
iucn_red_list_2020 = col_character(),
realm = col_character(),
cluster = col_double(),
cluster_half = col_double(),
cluster_double = col_double()
)
merlin_data
merlin_result <- dredge_and_subset(merlin_data)
Fixed term is "(Intercept)"
merlin_summ <- model_summary('merlin', 'species', merlin_result)
merlin_summ
birdlife_data <- load_species_data('birdlife')
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
scientific_name = col_character(),
regional_pool_count = col_double(),
city_count = col_double(),
pc1 = col_double(),
pc2 = col_double(),
pc3 = col_double(),
pc4 = col_double(),
trophic_niche = col_character(),
foraging_niche = col_character(),
is_noctural = col_logical(),
iucn_red_list_2020 = col_character(),
realm = col_character(),
cluster = col_double(),
cluster_half = col_double(),
cluster_double = col_double()
)
birdlife_result <- dredge_and_subset(birdlife_data)
Fixed term is "(Intercept)"
birdlife_summ <- model_summary('birdlife', 'species', birdlife_result)
birdlife_summ
both_data <- load_species_data('both')
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
scientific_name = col_character(),
regional_pool_count = col_double(),
city_count = col_double(),
pc1 = col_double(),
pc2 = col_double(),
pc3 = col_double(),
pc4 = col_double(),
trophic_niche = col_character(),
foraging_niche = col_character(),
is_noctural = col_logical(),
iucn_red_list_2020 = col_character(),
realm = col_character(),
cluster = col_double(),
cluster_half = col_double(),
cluster_double = col_double()
)
both_result <- dredge_and_subset(both_data)
Fixed term is "(Intercept)"
both_summ <- model_summary('both', 'species', both_result)
both_summ
either_data <- load_species_data('either')
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
scientific_name = col_character(),
regional_pool_count = col_double(),
city_count = col_double(),
pc1 = col_double(),
pc2 = col_double(),
pc3 = col_double(),
pc4 = col_double(),
trophic_niche = col_character(),
foraging_niche = col_character(),
is_noctural = col_logical(),
iucn_red_list_2020 = col_character(),
realm = col_character(),
cluster = col_double(),
cluster_half = col_double(),
cluster_double = col_double()
)
either_result <- dredge_and_subset(either_data)
Fixed term is "(Intercept)"
either_summ <- model_summary('either', 'species', either_result)
either_summ
all_species_results <- full_join(full_join(merlin_summ, birdlife_summ), full_join(both_summ, either_summ))
Joining, by = c("explanatory", "model")
Joining, by = c("explanatory", "model")
Joining, by = c("explanatory", "model")
write_csv(all_species_results, "species_result.csv")
merlin_data$source <- 'Merlin'
birdlife_data$source <- 'Birdlife'
both_data$source <- 'Both'
either_data$source <- 'Either'
plot_data <- rbind(merlin_data, birdlife_data, both_data, either_data)
ggplot(plot_data, aes(x = pc1, y = pc2, alpha = presence_ratio, color = as.factor(foraging_niche))) + geom_point() + theme(legend.position = "none") + facet_wrap(~ source)

ggplot(plot_data, aes(x = pc3, y = pc4, alpha = presence_ratio, color = as.factor(foraging_niche))) + geom_point() + theme(legend.position = "none") + facet_wrap(~ source)

library(ggpubr)
merlin_data$niche <- paste(merlin_data$trophic_niche, ' ', merlin_data$foraging_niche, ' ', merlin_data$is_noctural, ' ', merlin_data$cluster)
gg <- function(gg) {
gg + geom_point() + theme_bw() + labs(alpha="Presence Ratio", colour="Niche")
}
myplot <- ggarrange(
ncol = 2,
nrow = 2,
gg(ggplot(merlin_data, aes(x = pc1, y = pc3, alpha = presence_ratio, colour = niche)) + ylab("Short Tail + Pointy Beak -> Long Tail + Stubby Beak")) + theme(legend.position="none", axis.title.x=element_blank()) ,
gg(ggplot(merlin_data, aes(x = pc2, y = pc3, alpha = presence_ratio, colour = niche))) + theme(legend.position="none", axis.title.x=element_blank(), axis.title.y=element_blank()),
gg(ggplot(merlin_data, aes(x = pc1, y = pc4, alpha = presence_ratio, colour = niche)) + ylab("Long Tail + Pointy Beak -> Short Tail + Stubby Beak") + xlab("Body Size")) + theme(legend.position="none"),
gg(ggplot(merlin_data, aes(x = pc2, y = pc4, alpha = presence_ratio, colour = niche)) + xlab("Beak Size")) + theme(legend.position="none", axis.title.y=element_blank())
)
myplot <- annotate_figure(myplot, top = text_grob("Species Presence based on Morphology", face = "bold", size = 14),
bottom = text_grob("Colour: Niche, Alpha: Presence Ratio", hjust = 1, size = 10))
myplot

jpeg("species.jpg", width = 1024, height = 1024)
myplot
dev.off()
null device
1
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQpgYGB7cn0KbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShiaWdycXVlcnkpCmBgYAoKYGBge3J9CnJlc3BvbnNlIDwtIHRyeShzeXN0ZW0oJ34vZ29vZ2xlLWNsb3VkLXNkay9iaW4vZ2Nsb3VkIHByb2plY3RzIGxpc3QgLS1xdWlldCcsIGludGVybiA9IFQpKQpwcm9qZWN0aWQgPC0gc3Ryc3BsaXQocmVzcG9uc2VbMl0sICIgIilbWzFdXVsxXQpgYGAKCmBgYHtyfQpvcHRpb25zKG5hLmFjdGlvbiA9ICJuYS5mYWlsIikgCmBgYAoKYGBge3J9CnNvdXJjZSgiLi9kcmVkZ2VfZnVuY3Rpb25zLlIiKQpgYGAKCmBgYHtyfQpkcmVkZ2VfYW5kX3N1YnNldCA8LSBmdW5jdGlvbihkYXRhKSB7CiAgbW9kZWwgPC0gbG0oCiAgICBwcmVzZW5jZV9yYXRpbyB+IGZvcmFnaW5nX25pY2hlICsgdHJvcGhpY19uaWNoZSArIGlzX25vY3R1cmFsICsgcGMxICsgcGMyICsgcGMzICsgcGM0ICsgaXVjbl9yZWRfbGlzdF8yMDIwICsgcmVhbG0sCiAgICBkYXRhPWRhdGEKICApCiAgZHJlZGdlX3Jlc3VsdCA8LSBkcmVkZ2UobW9kZWwpCiAgc3VtbWFyeShtb2RlbC5hdmcoZHJlZGdlX3Jlc3VsdCwgc3Vic2V0ID0gZGVsdGEgPCAxMCkpCn0KYGBgCgpgYGB7cn0KbG9hZF9zcGVjaWVzX2RhdGEgPC0gZnVuY3Rpb24ocG9vbG5hbWUpIHsKICBmaWxlbmFtZSA8LSBzdHJfcmVwbGFjZSgnc3BlY2llc19tZXRyaWNzXyMjUE9PTF9OQU1FIyMuY3N2JywgJyMjUE9PTF9OQU1FIyMnLCBwb29sbmFtZSkKICAKICBpZiAoIWZpbGUuZXhpc3RzKGZpbGVuYW1lKSkgewogICAgY29sdW1uX25hbWUgPSBzdHJfcmVwbGFjZV9hbGwoJ3ByZXNlbnRfaW5fIyNQT09MX05BTUUjI19wb29sJywgJyMjUE9PTF9OQU1FIyMnLCBwb29sbmFtZSkKICAgIGlmIChwb29sbmFtZSA9PSAnYm90aCcpIHsKICAgICAgY29sdW1uX25hbWUgPSAncHJlc2VudF9pbl9ib3RoX3Bvb2xzJwogICAgfQogICAgCiAgICBzcWwgPC0gc3RyX3JlcGxhY2VfYWxsKCIKICAgICAgICAgV0lUSCBzcGVjaWVzIEFTICgKICAgICAgICAgICAgICBTRUxFQ1QgCiAgICAgICAgICAgICAgICAgIHNjaWVudGlmaWNfbmFtZSwKICAgICAgICAgICAgICAgICAgY291bnQoKikgQVMgcmVnaW9uYWxfcG9vbF9jb3VudCwKICAgICAgICAgICAgICAgICAgY291bnRpZihwcmVzZW50X2luX2NpdHkgPSB0cnVlKSBBUyBjaXR5X2NvdW50CiAgICAgICAgICAgICAgRlJPTSBtb2RlbC5yZWdpb25hbF9zcGVjaWVzX2ZpbHRlcmVkCiAgICAgICAgICAgICAgSk9JTiBtb2RlbC50YXhvbm9teSBVU0lORyAoc2NpZW50aWZpY19uYW1lKQogICAgICAgICAgICAgIFdIRVJFICMjQ09MX1NFTEVDVCMjID0gdHJ1ZQogICAgICAgICAgICAgIEdST1VQIEJZIHNjaWVudGlmaWNfbmFtZQogICAgICAgICAgKQogICAgICAgICAgU0VMRUNUIAogICAgICAgICAgICAgIHNwZWNpZXMuKiwKICAgICAgICAgICAgICBib2R5X21vcnBoc3BhY2UucGMxLAogICAgICAgICAgICAgIGJvZHlfbW9ycGhzcGFjZS5wYzIsCiAgICAgICAgICAgICAgYm9keV9tb3JwaHNwYWNlLnBjMywKICAgICAgICAgICAgICBib2R5X21vcnBoc3BhY2UucGM0LAogICAgICAgICAgICAgIHRyb3BoaWNfbmljaGUsCiAgICAgICAgICAgICAgZm9yYWdpbmdfbmljaGUsCiAgICAgICAgICAgICAgaXNfbm9jdHVyYWwsCiAgICAgICAgICAgICAgaXVjbl9yZWRfbGlzdF8yMDIwLAogICAgICAgICAgICAgIHJlYWxtLAogICAgICAgICAgICAgIHR0Yy5jbHVzdGVyLAogICAgICAgICAgICAgIHR0Yy5jbHVzdGVyX2hhbGYsCiAgICAgICAgICAgICAgdHRjLmNsdXN0ZXJfZG91YmxlCiAgICAgICAgICBGUk9NIHNwZWNpZXMKICAgICAgICAgIEpPSU4gbW9kZWwudGF4b25vbXkgVVNJTkcgKHNjaWVudGlmaWNfbmFtZSkKICAgICAgICAgIEpPSU4gZGF0YXNjaS50YXhvbm9taWNfdHJhaXRfY2x1c3RlcnMgdHRjIFVTSU5HIChzY2llbnRpZmljX25hbWUpIiwgJyMjQ09MX1NFTEVDVCMjJywgY29sdW1uX25hbWUpCiAgCiAgICB0YiA8LSBicV9wcm9qZWN0X3F1ZXJ5KHByb2plY3RpZCwgc3FsKQoKICAgIGRhdGEgPC0gYnFfdGFibGVfZG93bmxvYWQodGIpCiAgICB3cml0ZV9jc3YoZGF0YSwgZmlsZW5hbWUpCiAgfQogIAogIGRhdGEgPC0gcmVhZF9jc3YoZmlsZW5hbWUpCiAgCiAgZGF0YVtpcy5uYShkYXRhJGZvcmFnaW5nX25pY2hlKSxdJGZvcmFnaW5nX25pY2hlIDwtICdPbW5pdm9yZScKICAKICBkYXRhJGZvcmFnaW5nX25pY2hlID0gYXMuZmFjdG9yKGRhdGEkZm9yYWdpbmdfbmljaGUpCiAgZGF0YSR0cm9waGljX25pY2hlID0gYXMuZmFjdG9yKGRhdGEkdHJvcGhpY19uaWNoZSkKICBkYXRhJGlzX25vY3R1cmFsID0gYXMuZmFjdG9yKGRhdGEkaXNfbm9jdHVyYWwpCiAgZGF0YSRwcmVzZW5jZV9yYXRpbyA9IGRhdGEkY2l0eV9jb3VudCAvIGRhdGEkcmVnaW9uYWxfcG9vbF9jb3VudAogIGRhdGEkaXVjbl9yZWRfbGlzdF8yMDIwID0gYXMuZmFjdG9yKGRhdGEkaXVjbl9yZWRfbGlzdF8yMDIwKQogIGRhdGEkcmVhbG0gPSBhcy5mYWN0b3IoZGF0YSRyZWFsbSkKICAKICBkYXRhCn0KYGBgCgoKYGBge3J9Cm1lcmxpbl9kYXRhIDwtIGxvYWRfc3BlY2llc19kYXRhKCdtZXJsaW4nKQptZXJsaW5fZGF0YQpgYGAKCgoKYGBge3J9Cm1lcmxpbl9yZXN1bHQgPC0gZHJlZGdlX2FuZF9zdWJzZXQobWVybGluX2RhdGEpCm1lcmxpbl9zdW1tIDwtIG1vZGVsX3N1bW1hcnkoJ21lcmxpbicsICdzcGVjaWVzJywgbWVybGluX3Jlc3VsdCkKbWVybGluX3N1bW0KYGBgCgpgYGB7cn0KYmlyZGxpZmVfZGF0YSA8LSBsb2FkX3NwZWNpZXNfZGF0YSgnYmlyZGxpZmUnKQpiaXJkbGlmZV9yZXN1bHQgPC0gZHJlZGdlX2FuZF9zdWJzZXQoYmlyZGxpZmVfZGF0YSkKYmlyZGxpZmVfc3VtbSA8LSBtb2RlbF9zdW1tYXJ5KCdiaXJkbGlmZScsICdzcGVjaWVzJywgYmlyZGxpZmVfcmVzdWx0KQpiaXJkbGlmZV9zdW1tCmBgYAoKCmBgYHtyfQpib3RoX2RhdGEgPC0gbG9hZF9zcGVjaWVzX2RhdGEoJ2JvdGgnKQpib3RoX3Jlc3VsdCA8LSBkcmVkZ2VfYW5kX3N1YnNldChib3RoX2RhdGEpCmJvdGhfc3VtbSA8LSBtb2RlbF9zdW1tYXJ5KCdib3RoJywgJ3NwZWNpZXMnLCBib3RoX3Jlc3VsdCkKYm90aF9zdW1tCmBgYAoKCmBgYHtyfQplaXRoZXJfZGF0YSA8LSBsb2FkX3NwZWNpZXNfZGF0YSgnZWl0aGVyJykKZWl0aGVyX3Jlc3VsdCA8LSBkcmVkZ2VfYW5kX3N1YnNldChlaXRoZXJfZGF0YSkKZWl0aGVyX3N1bW0gPC0gbW9kZWxfc3VtbWFyeSgnZWl0aGVyJywgJ3NwZWNpZXMnLCBlaXRoZXJfcmVzdWx0KQplaXRoZXJfc3VtbQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KRnVsbCByZXN1bHQKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpgYGB7cn0KYWxsX3NwZWNpZXNfcmVzdWx0cyA8LSBmdWxsX2pvaW4oZnVsbF9qb2luKG1lcmxpbl9zdW1tLCBiaXJkbGlmZV9zdW1tKSwgZnVsbF9qb2luKGJvdGhfc3VtbSwgZWl0aGVyX3N1bW0pKQp3cml0ZV9jc3YoYWxsX3NwZWNpZXNfcmVzdWx0cywgInNwZWNpZXNfcmVzdWx0LmNzdiIpCmBgYAoKYGBge3J9Cm1lcmxpbl9kYXRhJHNvdXJjZSA8LSAnTWVybGluJwpiaXJkbGlmZV9kYXRhJHNvdXJjZSA8LSAnQmlyZGxpZmUnCmJvdGhfZGF0YSRzb3VyY2UgPC0gJ0JvdGgnCmVpdGhlcl9kYXRhJHNvdXJjZSA8LSAnRWl0aGVyJwoKcGxvdF9kYXRhIDwtIHJiaW5kKG1lcmxpbl9kYXRhLCBiaXJkbGlmZV9kYXRhLCBib3RoX2RhdGEsIGVpdGhlcl9kYXRhKQoKZ2dwbG90KHBsb3RfZGF0YSwgYWVzKHggPSBwYzEsIHkgPSBwYzIsIGFscGhhID0gcHJlc2VuY2VfcmF0aW8sIGNvbG9yID0gYXMuZmFjdG9yKGZvcmFnaW5nX25pY2hlKSkpICsgZ2VvbV9wb2ludCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArIGZhY2V0X3dyYXAofiBzb3VyY2UpCmBgYApgYGB7cn0KZ2dwbG90KHBsb3RfZGF0YSwgYWVzKHggPSBwYzMsIHkgPSBwYzQsIGFscGhhID0gcHJlc2VuY2VfcmF0aW8sIGNvbG9yID0gYXMuZmFjdG9yKGZvcmFnaW5nX25pY2hlKSkpICsgZ2VvbV9wb2ludCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArIGZhY2V0X3dyYXAofiBzb3VyY2UpCmBgYApgYGB7cn0KbGlicmFyeShnZ3B1YnIpCmBgYAoKYGBge3J9Cm1lcmxpbl9kYXRhJG5pY2hlIDwtIHBhc3RlKG1lcmxpbl9kYXRhJHRyb3BoaWNfbmljaGUsICcgJywgbWVybGluX2RhdGEkZm9yYWdpbmdfbmljaGUsICcgJywgbWVybGluX2RhdGEkaXNfbm9jdHVyYWwsICcgJywgbWVybGluX2RhdGEkY2x1c3RlcikKYGBgCgpgYGB7cn0KZ2cgPC0gZnVuY3Rpb24oZ2cpIHsKICBnZyArIGdlb21fcG9pbnQoKSArIHRoZW1lX2J3KCkgKyBsYWJzKGFscGhhPSJQcmVzZW5jZSBSYXRpbyIsIGNvbG91cj0iTmljaGUiKQp9CgpteXBsb3QgPC0gZ2dhcnJhbmdlKAogIG5jb2wgPSAyLAogIG5yb3cgPSAyLAogIGdnKGdncGxvdChtZXJsaW5fZGF0YSwgYWVzKHggPSBwYzEsIHkgPSBwYzMsIGFscGhhID0gcHJlc2VuY2VfcmF0aW8sIGNvbG91ciA9IG5pY2hlKSkgKyB5bGFiKCJTaG9ydCBUYWlsICsgUG9pbnR5IEJlYWsgLT4gTG9uZyBUYWlsICsgU3R1YmJ5IEJlYWsiKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLCBheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpKSAsCiAgZ2coZ2dwbG90KG1lcmxpbl9kYXRhLCBhZXMoeCA9IHBjMiwgeSA9IHBjMywgYWxwaGEgPSBwcmVzZW5jZV9yYXRpbywgY29sb3VyID0gbmljaGUpKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLCBheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLCBheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpKSwKICBnZyhnZ3Bsb3QobWVybGluX2RhdGEsIGFlcyh4ID0gcGMxLCB5ID0gcGM0LCBhbHBoYSA9IHByZXNlbmNlX3JhdGlvLCBjb2xvdXIgPSBuaWNoZSkpICsgeWxhYigiTG9uZyBUYWlsICsgUG9pbnR5IEJlYWsgLT4gU2hvcnQgVGFpbCArIFN0dWJieSBCZWFrIikgKyB4bGFiKCJCb2R5IFNpemUiKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSwKICBnZyhnZ3Bsb3QobWVybGluX2RhdGEsIGFlcyh4ID0gcGMyLCB5ID0gcGM0LCBhbHBoYSA9IHByZXNlbmNlX3JhdGlvLCBjb2xvdXIgPSBuaWNoZSkpICsgeGxhYigiQmVhayBTaXplIikpICArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsIGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCkpCikKbXlwbG90IDwtIGFubm90YXRlX2ZpZ3VyZShteXBsb3QsIHRvcCA9IHRleHRfZ3JvYigiU3BlY2llcyBQcmVzZW5jZSBiYXNlZCBvbiBNb3JwaG9sb2d5IiwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICBib3R0b20gPSB0ZXh0X2dyb2IoIkNvbG91cjogTmljaGUsIEFscGhhOiBQcmVzZW5jZSBSYXRpbyIsIGhqdXN0ID0gMSwgc2l6ZSA9IDEwKSkKbXlwbG90CmBgYAoKYGBge3J9CmpwZWcoInNwZWNpZXMuanBnIiwgd2lkdGggPSAxMDI0LCBoZWlnaHQgPSAxMDI0KQpteXBsb3QKZGV2Lm9mZigpCmBgYA==